package com.maple.utils;

import com.alipay.api.AlipayApiException;
import com.alipay.api.AlipayClient;
import com.alipay.api.AlipayConfig;
import com.alipay.api.DefaultAlipayClient;
import com.alipay.api.domain.*;
import com.alipay.api.internal.util.AlipaySignature;
import com.alipay.api.request.*;
import com.alipay.api.response.*;
import com.maple.properties.AlipayProperties;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;

import java.math.BigDecimal;
import java.util.*;


@Component
public class AlipayUtils {


    @Autowired
    static AlipayProperties alipayProperties;

    /**
     * 获得Alipay的客户端
     * @return
     */
    public static AlipayClient getAlipayClient(){
        return new DefaultAlipayClient(alipayProperties.getUrl(),
                alipayProperties.getAppId(),
                alipayProperties.getPrivateKey(),
                alipayProperties.getPrivateKey(),
                alipayProperties.getCharset(),
                alipayProperties.getAlipayPublicKey(),
                alipayProperties.getSignType());
    }

    /**
     * 获得登陆用户的令牌信息
     * @param authCode
     * @return
     * @throws AlipayApiException
     */
    public static AlipaySystemOauthTokenResponse getRequest(String authCode) throws AlipayApiException {
        AlipayClient alipayClient = getAlipayClient();
        AlipaySystemOauthTokenRequest request = new AlipaySystemOauthTokenRequest();
        request.setCode(authCode);
        request.setGrantType("authorization_code");
        AlipaySystemOauthTokenResponse response = alipayClient.execute(request);
        isSuccess(response);
        return response;
    }

    /**
     * 刷新alipay的令牌信息
     * @param accessToken
     * @return
     * @throws AlipayApiException
     */
    public static void parseAlipayToken(String accessToken) throws AlipayApiException {
        AlipayClient alipayClient = getAlipayClient();
        AlipaySystemOauthTokenRequest request = new AlipaySystemOauthTokenRequest();
        request.setGrantType("refresh_token");
        AlipaySystemOauthTokenResponse response = alipayClient.execute(request);
        isSuccess(response);
    }

    /**
     * 获得登陆用户的信息
     * @param accessToken
     * @return
     * @throws AlipayApiException
     */
    public static AlipayUserInfoShareResponse getUserInformation(String accessToken) throws AlipayApiException {
        AlipayClient alipayClient = getAlipayClient();
        AlipayUserInfoShareRequest request = new AlipayUserInfoShareRequest();
        AlipayUserInfoShareResponse response = alipayClient.execute(request,accessToken);
        if(response.isSuccess()){
            System.out.println("调用成功");
        } else {
            System.out.println("调用失败");
        }
        return response;
    }

    /**
     * 创建交易订单
     * @throws AlipayApiException
     */
     public static String buildOrder(String uuid, BigDecimal amount, String remark) throws AlipayApiException {
         // 初始化SDK
         AlipayClient alipayClient = getAlipayClient();

         // 构造请求参数以调用接口
         AlipayTradeCreateRequest request = new AlipayTradeCreateRequest();
         AlipayTradeCreateModel model = new AlipayTradeCreateModel();

         // 设置商户订单号
         model.setOutTradeNo(uuid);

         // 设置订单总金额
         model.setTotalAmount(String.valueOf(amount));

         // 设置订单标题
         model.setSubject("用户" + ThreadLocalUtils.getCurrentId() + "的外卖订单");

         // 设置产品码(固定写法：小程序支付)
         model.setProductCode("JSAPI_PAY");

         // 设置小程序支付中
         model.setOpAppId(alipayProperties.getAppId());

         // 设置订单附加信息
         model.setBody(remark);

         // 设置异步通知地址
         request.setNotifyUrl(alipayProperties.getNotifyUrl());

         // 设置同步跳转地址（可选）
//         request.setReturnUrl(alipayProperties.getRefundNotifyUrl());

//        // 设置业务扩展参数
//         ExtendParams extendParams = new ExtendParams();
//         extendParams.setTradeComponentOrderId("2023060801502300000008810000005657");
//         model.setExtendParams(extendParams);
//
//         // 设置可打折金额
//         model.setDiscountableAmount("80.00");
//
//         // uid参数未来计划废弃，存量商户可继续使用，新商户请使用openid。请根据应用-开发配置-openid配置选择支持的字段。
//         // model.setBuyerId("2088102146225135");
//
//         // 设置买家支付宝用户唯一标识
//         model.setBuyerOpenId("074a1CcTG1LelxKe4xQC0zgNdId0nxi95b5lsNpazWYoCo5");
//
//         // 设置商户门店编号
//         model.setStoreId("NJ_001");

         request.setBizModel(model);
         // 第三方代调用模式下请设置app_auth_token
         // request.putOtherTextParam("app_auth_token", "<-- 请填写应用授权令牌 -->");

         AlipayTradeCreateResponse response = alipayClient.execute(request);
         System.out.println(response.getBody());

         if (response.isSuccess()) {
             System.out.println("调用成功");
         } else {
             System.out.println("调用失败");
             // sdk版本是"4.38.0.ALL"及以上,可以参考下面的示例获取诊断链接
             // String diagnosisUrl = DiagnosisUtils.getDiagnosisUrl(response);
             // System.out.println(diagnosisUrl);
         }
         return response.getTradeNo();
     }

    /**
     * 取消订单
     * @param outTradeNo
     * @throws AlipayApiException
     */
    public static void cancelOrder(String outTradeNo) throws AlipayApiException {
        // 初始化SDK
        AlipayClient alipayClient = getAlipayClient();

        // 构造请求参数以调用接口
        AlipayTradeCancelRequest request = new AlipayTradeCancelRequest();
        AlipayTradeCancelModel model = new AlipayTradeCancelModel();

        // 设置原支付请求的商户订单号
        model.setOutTradeNo(outTradeNo);

        // 设置支付宝交易号
//        model.setTradeNo("2014112611001004680073956707");

        request.setBizModel(model);
        // 第三方代调用模式下请设置app_auth_token
        // request.putOtherTextParam("app_auth_token", "<-- 请填写应用授权令牌 -->");

        AlipayTradeCancelResponse response = alipayClient.execute(request);
        System.out.println(response.getBody());

        if (response.isSuccess()) {
            System.out.println("调用成功");
        } else {
            System.out.println("调用失败");
            // sdk版本是"4.38.0.ALL"及以上,可以参考下面的示例获取诊断链接
            // String diagnosisUrl = DiagnosisUtils.getDiagnosisUrl(response);
            // System.out.println(diagnosisUrl);
        }
    }

    /**
     * 拒单
     * @param amount
     * @param outTradeNo
     * @param rejectionReason
     * @throws AlipayApiException
     */
    public static void rejection(BigDecimal amount, String outTradeNo, String rejectionReason) throws AlipayApiException {
        // 初始化SDK
        AlipayClient alipayClient = getAlipayClient();

        // 构造请求参数以调用接口
        AlipayTradeRefundRequest request = new AlipayTradeRefundRequest();
        AlipayTradeRefundModel model = new AlipayTradeRefundModel();

        // 设置退款金额
        model.setRefundAmount(String.valueOf(amount));

        // 设置商户订单号
        model.setOutTradeNo(outTradeNo);

        // 设置退款原因说明
        model.setRefundReason(rejectionReason);

        // 设置退款请求号
//        model.setOutRequestNo("HZ01RF001");

        // 设置支付宝交易号
//        model.setTradeNo("2014112611001004680073956707");

        // 设置退款包含的商品列表信息
//        List<RefundGoodsDetail> refundGoodsDetail = new ArrayList<RefundGoodsDetail>();
//        RefundGoodsDetail refundGoodsDetail0 = new RefundGoodsDetail();
//        refundGoodsDetail0.setOutSkuId("outSku_01");
//        refundGoodsDetail0.setOutItemId("outItem_01");
//        refundGoodsDetail0.setGoodsId("apple-01");
//        refundGoodsDetail0.setRefundAmount("19.50");
//        List<String> outCertificateNoList = new ArrayList<String>();
//        outCertificateNoList.add("202407013232143241231243243423");
//        refundGoodsDetail0.setOutCertificateNoList(outCertificateNoList);
//        refundGoodsDetail.add(refundGoodsDetail0);
//        model.setRefundGoodsDetail(refundGoodsDetail);

        // 设置退分账明细信息
//        List<OpenApiRoyaltyDetailInfoPojo> refundRoyaltyParameters = new ArrayList<OpenApiRoyaltyDetailInfoPojo>();
//        OpenApiRoyaltyDetailInfoPojo refundRoyaltyParameters0 = new OpenApiRoyaltyDetailInfoPojo();
//        refundRoyaltyParameters0.setAmount("0.1");
//        refundRoyaltyParameters0.setTransIn("2088101126708402");
//        refundRoyaltyParameters0.setRoyaltyType("transfer");
//        refundRoyaltyParameters0.setTransOut("2088101126765726");
//        refundRoyaltyParameters0.setTransOutType("userId");
//        refundRoyaltyParameters0.setRoyaltyScene("达人佣金");
//        refundRoyaltyParameters0.setTransInType("userId");
//        refundRoyaltyParameters0.setTransInName("张三");
//        refundRoyaltyParameters0.setDesc("分账给2088101126708402");
//        refundRoyaltyParameters.add(refundRoyaltyParameters0);
//        model.setRefundRoyaltyParameters(refundRoyaltyParameters);

        // 设置查询选项
        List<String> queryOptions = new ArrayList<String>();
        queryOptions.add("refund_detail_item_list");
        model.setQueryOptions(queryOptions);

        // 设置针对账期交易,是账期交易（例如涉及延迟结算或分账等情况），并且退款发生在确认结算之后
//        model.setRelatedSettleConfirmNo("2024041122001495000530302869");

        request.setBizModel(model);
        // 第三方代调用模式下请设置app_auth_token
        // request.putOtherTextParam("app_auth_token", "<-- 请填写应用授权令牌 -->");

        AlipayTradeRefundResponse response = alipayClient.execute(request);
        System.out.println(response.getBody());

        if (response.isSuccess()) {
            System.out.println("调用成功");
        } else {
            System.out.println("调用失败");
            // sdk版本是"4.38.0.ALL"及以上,可以参考下面的示例获取诊断链接
            // String diagnosisUrl = DiagnosisUtils.getDiagnosisUrl(response);
            // System.out.println(diagnosisUrl);
        }
    }

    /**
     * 支付成功的异步请求数据处理
     * @param request
     * @param response
     * @return
     */
    public static Map<String,String> paySuccess(HttpServletRequest request, HttpServletResponse response){
        //获取支付宝POST过来反馈信息
        Map<String,String> params = new HashMap<String,String>();
        Map requestParams = request.getParameterMap();
        for (Iterator iter = requestParams.keySet().iterator(); iter.hasNext();) {
            String name = (String) iter.next();
            String[] values = (String[]) requestParams.get(name);
            String valueStr = "";
            for (int i = 0; i < values.length; i++) {
                valueStr = (i == values.length - 1) ? valueStr + values[i]
                        : valueStr + values[i] + ",";
            }
            //乱码解决，这段代码在出现乱码时使用。
            //valueStr = new String(valueStr.getBytes("ISO-8859-1"), "utf-8");
            params.put(name, valueStr);
        }

        // 移除 sign 和 sign_type 参数
        String sign = params.remove("sign");
        String signType = params.remove("sign_type");

        return params;
    }


    /**
     * 校验支付宝接口是否调用成功
     * @param response
     */
    public static void isSuccess(AlipaySystemOauthTokenResponse response){
        if(!response.isSuccess()){
            throw new RuntimeException();
        }
    }

}
